﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace SoftSocket
{
    public partial class FrmSoftSocket : Form
    {
        const string _serverIP = "121.196.201.131";
        const string _localIP = "192.168.0.102";
        const int _serverPort = 7818;
        enum GETID { Free, GetID, WaitID, WriteID };

        Socket socketLink = null;
        Thread _receiveThread = null;
        Thread _sendThread = null;


        public FrmSoftSocket()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 将字符串转为Ascii 的十六进制
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        static public byte[] StringToAsciiByte(string str)
        {
            return System.Text.Encoding.ASCII.GetBytes(str);
        }

        /// <summary>
        /// 将Ascii的十六进制数组转化为字符串
        /// </summary>
        /// <param name="byteArray"></param>
        /// <returns></returns>
        static public string AsciiByteToString(byte[] byteArray)
        {
            return System.Text.Encoding.ASCII.GetString(byteArray);
        }

        private void butLogin_Click(object sender, EventArgs e)
        {
            //if (butLogin.Enabled == true)
            if(butLogin.Text == "登录")
            {
                //butLogin.Enabled = false;
                Logining();
                butLogin.Text = "退出";
            }
            else if(butLogin.Text == "退出")
            {
                butLogin.Text = "登录";

                if(socketLink != null)
                {
                    socketLink.Close();
                    socketLink = null;
                }

                if(_receiveThread != null)
                {
                    _receiveThread.Abort();
                    _receiveThread = null;
                }
            }
        }

        private void Logining()
        {
            string ipstr = _localIP;
            socketLink = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //将字符串地址转化为网际协议地址
            //if(cbInternel.Checked == true)
            //{
            //    ipstr = _serverIP;
            //}
            //else
            //{
            //    ipstr = _localIP;
            //}
            ipstr = tbServerIP.Text.Trim();
            IPAddress ipAddress = IPAddress.Parse(ipstr);
            //使用指定地址和端口号实例化新的网络端点
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, _serverPort);

            socketLink.Connect(remoteEP);

            if (_receiveThread == null)
            {
                _receiveThread = new Thread(ReceiveData);
                _receiveThread.IsBackground = true;
                _receiveThread.Start(socketLink);
            }

            
        }

        private void ReceiveData(object oLink)
        {
            Socket sLink = oLink as Socket;
            int idOKFlag = 0;
            byte[] receiveBuf = new byte[2048];

            string LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
            byte[] sendbuf = StringToAsciiByte(LoginInfo);
            sLink.Send(sendbuf);
            DisplayMsg("发送：" + LoginInfo);
            while (true)
            {
                try {
                    int recLen = sLink.Receive(receiveBuf);
                    if (recLen == 0)
                    {
                        socketLink.Close();
                        socketLink = null;
                        timer1.Enabled = false;
                        break;
                    }
                } catch { }


                if (idOKFlag == 1) idOKFlag = 2;

                string recCmd = AsciiByteToString(receiveBuf);
                DisplayMsg("接收：" + recCmd);
                switch (recCmd)
                {
                    case "ERROR1\r\n":
                        LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
                        sendbuf = StringToAsciiByte(LoginInfo);
                        sLink.Send(sendbuf);
                        break;
                    case "ERROR2\r\n":
                        LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
                        sendbuf = StringToAsciiByte(LoginInfo);
                        sLink.Send(sendbuf);
                        break;
                    case "ERROR3\r\n":
                        LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
                        sendbuf = StringToAsciiByte(LoginInfo);
                        sLink.Send(sendbuf);
                        break;
                    case "ERROR4\r\n":
                        LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
                        sendbuf = StringToAsciiByte(LoginInfo);
                        sLink.Send(sendbuf);
                        break;
                    case "ERROR\r\n":
                        //LoginInfo = "AT+USERS=" + tbuser.Text.Trim() + "," + tbpw.Text.Trim() + "\r\n";
                        //sendbuf = StringToAsciiByte(LoginInfo);
                        //sLink.Send(sendbuf);
                        idOKFlag = 0;
                        break;
                    case "OK\r\n":
                        this.Invoke(new EventHandler(delegate
                        {
                            timer1.Interval = 3000;
                            timer1.Enabled = true;
                        }));
                        break;
                    
                    default:
                        if (idOKFlag == 0)
                        {
                            string idStr = "AT+ID=" + tbID1.Text.Trim() + "\r\n";
                            DisplayMsg("发送：" + idStr);
                            sendbuf = StringToAsciiByte(idStr);
                            sLink.Send(sendbuf);
                            idOKFlag = 1;
                        }
                        break;
                }

                if (idOKFlag == 2) idOKFlag = 3;

            }
        }

        private void butRelayClose1_Click(object sender, EventArgs e)
        {
            rebootTime();
            Button but = sender as Button;
            //AT+STACHn 
            string cmd = "AT+STACH" + but.Tag.ToString() + "=1\r\n";
            SendCtlCmd(cmd);
        }

        private void SendCtlCmd(string cmd)
        {
            try
            {
                if(socketLink != null)
                {
                    DisplayMsg("发送："+cmd);
                    byte[] sdata = StringToAsciiByte("<" + tbID1.Text.Trim() + ">," + cmd);
                    socketLink.Send(sdata);
                }
            }
            catch { }
        }

        private void butRelayOpen1_Click(object sender, EventArgs e)
        {
            rebootTime();
            Button but = sender as Button;
            //AT+STACHn 
            string cmd = "AT+STACH" + but.Tag.ToString() + "=0\r\n";
            SendCtlCmd(cmd);
        }

        private void FrmSoftSocket_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (socketLink != null)
            {
                socketLink.Close();
                socketLink = null;
                timer1.Enabled = false;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if(socketLink != null)
            {
                string cmd = "AT\r\n";
                DisplayMsg("发送：" + cmd);
                byte[] sendbuf = StringToAsciiByte(cmd);
                socketLink.Send(sendbuf);
            }
        }

        private void rebootTime()
        {
            timer1.Enabled = false;
            timer1.Interval = 3000;
            timer1.Enabled = true;
        }

        private void DisplayMsg(string msg)
        {
            this.Invoke(new EventHandler(delegate
            {
                lstMsg.Items.Add(msg);
                lstMsg.SelectedIndex = lstMsg.Items.Count - 1;
            }));
        }

        private void lstMsg_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (lstMsg.Items.Count > 0) lstMsg.Items.Clear();
        }

        private void 清除显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lstMsg.Items.Count > 0) lstMsg.Items.Clear();
        }
    }
}
